﻿//This BotBase was created by Apoc, I take no credit for anything within this code
//I just changed "!StyxWoW.Me.CurrentTarget.IsFriendly" to "!StyxWoW.Me.CurrentTarget.IsHostile"
//For the purpose of allowing RaidBot to work within Arenas

using System.Runtime.InteropServices;
using System.Windows.Forms;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Profiles;
using Styx.CommonBot.Routines;
using Styx.WoWInternals;
using Styx.TreeSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Documents;
using System.Windows.Media;
using CommonBehaviors.Actions;
using Styx;
using Styx.Common;
using Styx.CommonBot;
using Styx.CommonBot.Routines;
using Styx.TreeSharp;
using Styx.WoWInternals;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;



namespace Simcraft
{
	public partial class SimcraftImpl : BotBase
	{
		private Composite _root;
		public override string Name { get { return "Simcraft Impl"; } }
		public override Composite Root { get { return _root ?? (_root = new PrioritySelector(CreateRootBehavior())); } }
		public override PulseFlags PulseFlags { get { return PulseFlags.All & ~(PulseFlags.Targeting | PulseFlags.Looting); } }
		public bool IsPaused { get; set; }
        private static WoWClass _class = StyxWoW.Me.Class;
        public WoWClass Class { get { return StyxWoW.Me.Class; } }
        public static WoWContext Context = WoWContext.PvE;
        public static LocalPlayer Me { get { return StyxWoW.Me; } }
        public static WoWUnit MeU { get { return StyxWoW.Me.ToUnit(); } }
        public static WoWUnit TargetU { get { return StyxWoW.Me.CurrentTarget; } }
        public static HealthProxy Health = new HealthProxy(() => StyxWoW.Me.ToUnit());
        public static EnergyProxy Energy = new EnergyProxy(() => StyxWoW.Me.ToUnit());
        public static ChiProxy Chi = new ChiProxy(() => StyxWoW.Me.ToUnit());
        public static RageProxy Rage = new RageProxy(() => StyxWoW.Me.ToUnit());
        public static BuffProxy Buff = new BuffProxy();
        public static DebuffProxy Debuff = new DebuffProxy();
        public static TalentProxy Talent = new TalentProxy();
        public static CooldownProxy Cooldown = new CooldownProxy();
        public static TargetProxy Target = new TargetProxy();
        public static SpellProxy Spell = new SpellProxy();
        private static Boolean _aoeEnabled = false;
        private static Boolean _damageEnabled = false;
	    private CombatRoutine _oldRoutine;
	    private static WoWPoint _clickLocation = default(WoWPoint);
	    private static String _clickSpell = "";
	    private static int ite = 0;

        public Composite CombatIteration()
        {
            return new Action(delegate(object context)
            {
                if (_clickLocation != default(WoWPoint))
                {
                    //Logging.Write("Clicking " + _clickLocation);
                    SpellManager.ClickRemoteLocation(_clickLocation);
                    _clickLocation = default(WoWPoint);
                }
                CooldownsEnabled(true);
                AoeEnabled(true);
                DamageEnabled(true);
                Energy.Pulse();
                return RunStatus.Failure;
            });
        }

	    private void CombatEvent(object sender, LuaEventArgs args)
	    {
	        //if (args.Args[1].ToString() == StyxWoW.Me.Guid.ToString() && _clickLocation != default(WoWPoint))
	        //_clickLocation = default (WoWPoint);
	    }

	    public override void Initialize()
	    {
            Lua.Events.AttachEvent("COMBAT_LOG_EVENT_UNFILTERED", CombatEvent);
            Lua.Events.AttachEvent("CHARACTER_POINTS_CHANGED", ContextChange);
            Lua.Events.AttachEvent("PLAYER_ENTERING_WORLD", ContextChange);

            Logging.Write("===============================");
            Logging.Write("LETS HOPE WE DIDNT GET ANY COMPILE ERRORS");
            Logging.Write("===============================");
            ContextChange(null, null);
        }

        private void ContextChange(object sender, LuaEventArgs args)
        {
            Talent.Reset();
            _class = StyxWoW.Me.Class;
            var oldctx = Context;
            Context = (StyxWoW.Me.CurrentMap.IsArena || StyxWoW.Me.CurrentMap.IsBattleground) ? WoWContext.PvP : WoWContext.PvE;
            if (Context != oldctx) Logging.Write("Switching to " + Context + " Mode");
        }

	    public override void Start()
		{
			TreeRoot.TicksPerSecond = 10;
		    ProfileManager.LoadEmpty();
            _oldRoutine = RoutineManager.Current; //Save it so we can restore it later
            RoutineManager.Current = new ProxyRoutine();

			HotkeysManager.Register("Simcraft Pause",
				Keys.X,
				ModifierKeys.Alt,
				hk =>
					{
						IsPaused = !IsPaused;
						if (IsPaused)
						{
							Lua.DoString("print('Execution Paused!')");
							// Make the bot use less resources while paused.
							TreeRoot.TicksPerSecond = 1;
						}
						else
						{
                            Lua.DoString("print('Execution Resumed!')");
							// Kick it back into overdrive!
							TreeRoot.TicksPerSecond = 10;
						}
					});
		}


	    private Composite CreateRootBehavior()
	    {
	        return
	            new PrioritySelector(
	                new Decorator(ret => IsPaused,
	                    new Action(ret => RunStatus.Success)),
                        CombatIteration(),
	                new Decorator(ret => StyxWoW.Me.Combat,
	                    new LockSelector(
	                        new Decorator(
                                ret => StyxWoW.Me.GotTarget && !StyxWoW.Me.CurrentTarget.IsFriendly,
	                            Combat))));
	    }

	    public override void Stop()
		{
			TreeRoot.ResetTicksPerSecond();
	        RoutineManager.Current = _oldRoutine;
            HotkeysManager.Unregister("Simcraft Pause");
		}

		#region Nested types
        private class ProxyRoutine : CombatRoutine
        {
            public override string Name
            {
                get { return "Nullroutine"; }
            }

            public override WoWClass Class
            {
                get { return StyxWoW.Me.Class; }
            }
        }

		private class LockSelector : PrioritySelector
		{
			public LockSelector(params Composite[] children) : base(children)
			{
			}

			public override RunStatus Tick(object context)
			{
				using (StyxWoW.Memory.AcquireFrame())
				{
					return base.Tick(context);
				}
			}
		}

		#endregion

	    public static Composite Combat
	    {
            
	        get
	        {
	            switch (StyxWoW.Me.Class)
	            {
	                case WoWClass.Monk:
                        return Context == WoWContext.PvE ? MonkCombat() : MonkCombat();       
                    case WoWClass.Warrior:
                        return Context == WoWContext.PvE ? WarriorCombat() : WarriorPvPCombat();   
	            }

	            return new ActionAlwaysSucceed();
	        }
	    }


	}

    #region enums
    public enum WoWContext
    {
        PvP,
        PvE
    }
    #endregion
}